%%%-------------------------------------------------------------------
%%% @author liuwentao
%%% @doc
%%%     客户端连接校验协议
%%% @end
%%% Created : 02. 7月 2021 20:20
%%%-------------------------------------------------------------------

-module(client_rpc_open).
-export([
    handle/3
]).

-include("common.hrl").
-include("role.hrl").
-include("conn.hrl").

%% @doc 创建账号
handle(1010, {Account, _ClientType, Platform, ZoneId, _Args}, Conn = #conn{ip = {P1, P2, P3, P4}, port = Port, account = ""}) ->
    ?DEBUG("帐号[~ts]的客户端[~w]验证通过", [Account, _ClientType]),
    erlang:register(list_to_atom(lists:concat(["conn_", binary_to_list(unicode:characters_to_binary(Account)), "_", P1, "_", P2, "_", P3, "_", P4, "_", Port])), self()), %% 注册一个名字，方便查看进程状态
    NewConn = Conn#conn{account = Account, platform = Platform, zone_id = ZoneId},
    NewLocals = case env:get(combine) of
                    Locals when is_list(Locals) -> Locals;
                    _ -> []
                end,
    Local = {env:get(platform), env:get(zone_id)},
    Version = env:get(version),
    List = [Local | NewLocals],
    {reply, {?true, "", List, Version}, NewConn};


%% @doc 退出账号
handle(1020, {}, #conn{account = _Account}) ->
    ?DEBUG("账号[~ts]请求正常退出", [_Account]),
    stop;

%% 接收心跳包（测试ping值）
handle(1099, {Ping}, Conn) ->
    case speedup_check(true, Ping, Conn) of
        stop ->
            stop;
        {true, Ping, ServerTime} ->
            {reply, {Ping, ServerTime}};
        {true, Ping, ServerTime, NewConn} ->
            {reply, {Ping, ServerTime}, NewConn}
    end;



%% 容错匹配
handle(_Cmd, _Data, _Role) ->
    ?DEBUG("模块[~w]收到无效的RPC调用[~w]: ~w", [?MODULE, _Cmd, _Data]),
    {error, unknow_command}.



%% 是否开启加速校验
speedup_check(false, Ping, _) ->
    ServerTime = date:unixtime(),
    {true, Ping, ServerTime};
speedup_check(_, Ping, Conn = #conn{bad_heart_time = OldBadHeartTime, exact_heart_time = OldExactHeartTime, pid_object = _RolePid}) ->
    ServerTime = date:unixtime(),
    case get(last_heart_time) of
        undefined ->
            put(last_heart_time, ServerTime),
            %% 增加心跳包记录
            put(heart_timeout_info, [{ServerTime, Ping}]),
            NewConn = Conn#conn{bad_heart_time = 0, exact_heart_time = 1},
            {true, Ping, ServerTime, NewConn};
        ServerTime ->
            %% 重复的包计算
            ?DEBUG("重复的心跳包"),
            {true, Ping, ServerTime};
        LastHeartTime ->
            put(last_heart_time, ServerTime),
            case (ServerTime =< LastHeartTime + 6) of
                true ->  %% 当前心跳太短
                    NewExactHeartTime = 0,
                    NewBadHeartTime = OldBadHeartTime + 1,
                    NewConn = Conn#conn{bad_heart_time = NewBadHeartTime, exact_heart_time = NewExactHeartTime},
                    %% 增加心跳包记录
                    put(heart_timeout_info, [{ServerTime, Ping} | get(heart_timeout_info)]),
                    if
                        NewBadHeartTime >= 10 ->
                            ?DEBUG("关闭角色--NewBadHeartTime:~w, NewExactHeartTime:~w", [NewBadHeartTime, NewExactHeartTime]),
%%                            ConnPid = self(),
%%                            spawn(fun() ->
%%                                        sys_conn:pack_send(ConnPid, 14701, {"0", ?T("网络不稳定，请重新开启游戏")}),
%%                                        util:sleep(500),
%%                                        %% 强制关闭之前的连接器
%%                                        erlang:exit(ConnPid, kill)
%%                                end),
                            ?INFO("检测到加速!!强制断开连接!【~w】NewBadHeartTime ~w heart_timeout_info ~w", [Conn#conn.account, NewBadHeartTime, get(heart_timeout_info)]),
                            put(heart_timeout_info, [{ServerTime, Ping}]),
                            {true, Ping, ServerTime, NewConn};
                        NewBadHeartTime >= 3 ->
                            ?DEBUG("警告--NewBadHeartTime:~w, NewExactHeartTime:~w", [NewBadHeartTime, NewExactHeartTime]),
                            ?INFO("检测到加速!!警告玩家!【~w】NewBadHeartTime ~w heart_timeout_info ~w", [Conn#conn.account, NewBadHeartTime, get(heart_timeout_info)]),
%%                            notice:send({conn_pid, self()}, ?notice_chat, ?T("网络不稳定中，请切换到稳定网络")),
                            {true, Ping, ServerTime, NewConn};
                        true ->
                            ?DEBUG("错误计数--NewBadHeartTime:~w, NewExactHeartTime:~w", [NewBadHeartTime, NewExactHeartTime]),
                            {true, Ping, ServerTime, NewConn}
                    end;
                false ->
                    %% 正常包8个之后就清空错误计数
                    NewExactHeartTime = min(20, OldExactHeartTime + 1),
                    NewBadHeartTime = case NewExactHeartTime >= 3 of
                                          true ->
                                              %% 增加心跳包记录
                                              put(heart_timeout_info, [{ServerTime, Ping}]),
                                              0;
                                          false ->
                                              OldBadHeartTime
                                      end,
                    NewConn = Conn#conn{bad_heart_time = NewBadHeartTime, exact_heart_time = NewExactHeartTime},
                    {true, Ping, ServerTime, NewConn}
            end
    end.